const winston = require('winston');
require('winston-daily-rotate-file');
const path = require('path');

// 创建日志目录
const logDir = 'logs';
if (!require('fs').existsSync(logDir)) {
  require('fs').mkdirSync(logDir);
}

// 定义日志格式
const logFormat = winston.format.combine(
  winston.format.timestamp({
    format: 'YYYY-MM-DD HH:mm:ss'
  }),
  winston.format.json()
);

// 创建控制台输出的格式
const consoleFormat = winston.format.combine(
  winston.format.colorize(),
  winston.format.timestamp({
    format: 'YYYY-MM-DD HH:mm:ss'
  }),
  winston.format.printf(({ timestamp, level, message, ...meta }) => {
    // API 请求日志的特殊格式
    if (message === 'HTTP Request') {
      const { method, url, status, duration, ip } = meta;
      return `${timestamp} [${level}] ${method} ${url} - ${status} - ${duration} - ${ip}`;
    }
    // 错误日志的特殊格式
    if (message === 'Error occurred') {
      const { error, request } = meta;
      return `${timestamp} [${level}] ${request.method} ${request.url} - ${error.message}`;
    }
    // 默认格式
    const metaStr = Object.keys(meta).length ? JSON.stringify(meta) : '';
    return `${timestamp} [${level}] ${message} ${metaStr}`;
  })
);

// 创建按天分割的传输器
const dailyRotateFileTransport = new winston.transports.DailyRotateFile({
  filename: path.join(logDir, '%DATE%-combined.log'),
  datePattern: 'YYYY-MM-DD',
  maxSize: '20m',
  maxFiles: '7d',
  format: logFormat
});

// 创建错误日志的按天分割传输器
const errorRotateFileTransport = new winston.transports.DailyRotateFile({
  filename: path.join(logDir, '%DATE%-error.log'),
  datePattern: 'YYYY-MM-DD',
  maxSize: '20m',
  maxFiles: '7d',
  level: 'error',
  format: logFormat
});

// 创建 logger 实例
const logger = winston.createLogger({
  level: process.env.NODE_ENV === 'development' ? 'debug' : 'info',
  format: logFormat,
  transports: [
    // 输出到控制台
    new winston.transports.Console({
      format: consoleFormat
    }),
    // 按天分割的日志文件
    dailyRotateFileTransport,
    // 按天分割的错误日志文件
    errorRotateFileTransport
  ],
  // 异常处理
  exceptionHandlers: [
    new winston.transports.DailyRotateFile({
      filename: path.join(logDir, '%DATE%-exceptions.log'),
      datePattern: 'YYYY-MM-DD',
      maxSize: '20m',
      maxFiles: '7d',
      format: logFormat
    })
  ],
  // 退出时处理
  exitOnError: false
});

// 添加日志辅助方法
logger.logRequest = (req, res, next) => {
  const startTime = new Date();
  
  // 请求结束时记录日志
  res.on('finish', () => {
    const duration = new Date() - startTime;
    logger.info('HTTP Request', {
      method: req.method,
      url: req.originalUrl || req.url,
      status: res.statusCode,
      duration: `${duration}ms`,
      ip: req.ip,
      user: req.user ? req.user.id : 'anonymous',
      userAgent: req.get('user-agent')
    });
  });

  next();
};

// 错误日志方法
logger.logError = (err, req, res, next) => {
  logger.error('Error occurred', {
    error: {
      message: err.message,
      stack: err.stack
    },
    request: {
      method: req.method,
      url: req.originalUrl || req.url,
      body: req.body,
      query: req.query,
      params: req.params,
      ip: req.ip,
      user: req.user ? req.user.id : 'anonymous'
    }
  });
  next(err);
};

module.exports = logger; 